import { Animation, _decorator } from "cc";
import { ENTITY_STATE_ENUM, PARAM_NAME_ENUM } from "../../Enums";
import StateMachine, { getInitParamsNumber, getInitParamTrigger } from "../../Base/StateMachine";
import IdleSubStateMachine from "./IdleSubStateMachine";
import TurnLeftSubStateMachine from "./TurnLeftSubStateMachine";
import BlockFrontSubStateMachine from "./BlockFrontSubStateMachine";
import { EntityManager } from "../../Base/EntityManager";
import BlockTurnLeftSubStateMachine from "./BlockTurnLeftSubStateMachine";
import BlockBackSubStateMachine from "./BlockBackSubStateMachine";
import BlockLeftSubStateMachine from "./BlockLeftSubStateMachine";
import BlockRightSubStateMachine from "./BlockRightSubStateMachine";
import DeathSubStateMachine from "./DeathSubStateMachine";
import AttackSubStateMachine from "./AttackSubStateMachine";
import AireDeathSubStateMachine from "./AirDeathSubStateMachine";

const {ccclass, property} = _decorator

type ParamsValueType = boolean | number

@ccclass('PlayerStateMachine')
export class PlayerStateMachine extends StateMachine {
  async init() {
    this.animationComponent = this.addComponent(Animation)
    this.initParams()
    this.initStateMachines()
    this.initAnimationEvent()

    await Promise.all(this.waitingList)
  }
  initAnimationEvent() {
    this.animationComponent.on(Animation.EventType.FINISHED, () => {
      const name = this.animationComponent.defaultClip.name
      const whiteList = ['block', 'turn', 'attack']
      if (whiteList.some(v => name.includes(v))) {
        this.node.getComponent(EntityManager).state = ENTITY_STATE_ENUM.IDLE
      }
    })
  }
  initStateMachines() {
    this.stateMachines.set(PARAM_NAME_ENUM.IDLE, new IdleSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.TURNLEFT, new TurnLeftSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.BLOCKFRONT, new BlockFrontSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.BLOCKTURNLEFT, new BlockTurnLeftSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.BLOCKBACK, new BlockBackSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.BLOCKLEFT, new BlockLeftSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.BLOCKRIGHT, new BlockRightSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.DEATH, new DeathSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.AIRDEATH, new AireDeathSubStateMachine(this))
    this.stateMachines.set(PARAM_NAME_ENUM.ATTACK, new AttackSubStateMachine(this))
  }

  initParams() {
    this.params.set(PARAM_NAME_ENUM.IDLE, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.TURNLEFT, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.DIRECTION, getInitParamsNumber())
    this.params.set(PARAM_NAME_ENUM.BLOCKFRONT, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.BLOCKTURNLEFT, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.BLOCKBACK, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.BLOCKLEFT, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.BLOCKRIGHT, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.DEATH, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.AIRDEATH, getInitParamTrigger())
    this.params.set(PARAM_NAME_ENUM.ATTACK, getInitParamTrigger())
  }

  run() {
    switch (this.currentState) {
      case this.stateMachines.get(PARAM_NAME_ENUM.TURNLEFT):
      case this.stateMachines.get(PARAM_NAME_ENUM.BLOCKFRONT):
      case this.stateMachines.get(PARAM_NAME_ENUM.BLOCKTURNLEFT):
      case this.stateMachines.get(PARAM_NAME_ENUM.BLOCKBACK):
      case this.stateMachines.get(PARAM_NAME_ENUM.BLOCKLEFT):
      case this.stateMachines.get(PARAM_NAME_ENUM.BLOCKRIGHT):
      case this.stateMachines.get(PARAM_NAME_ENUM.IDLE):
      case this.stateMachines.get(PARAM_NAME_ENUM.DEATH):
      case this.stateMachines.get(PARAM_NAME_ENUM.AIRDEATH):
      case this.stateMachines.get(PARAM_NAME_ENUM.ATTACK):
        if (this.params.get(PARAM_NAME_ENUM.BLOCKFRONT).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.BLOCKFRONT)
        } else if (this.params.get(PARAM_NAME_ENUM.ATTACK).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.ATTACK)
        } else if (this.params.get(PARAM_NAME_ENUM.AIRDEATH).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.AIRDEATH)
        } else if (this.params.get(PARAM_NAME_ENUM.DEATH).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.DEATH)
        }else if (this.params.get(PARAM_NAME_ENUM.BLOCKTURNLEFT).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.BLOCKTURNLEFT)
        } else if (this.params.get(PARAM_NAME_ENUM.TURNLEFT).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.TURNLEFT)
        } else if (this.params.get(PARAM_NAME_ENUM.IDLE).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.IDLE)
        } else if (this.params.get(PARAM_NAME_ENUM.BLOCKBACK).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.BLOCKBACK)
        } else if (this.params.get(PARAM_NAME_ENUM.BLOCKLEFT).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.BLOCKLEFT)
        } else if (this.params.get(PARAM_NAME_ENUM.BLOCKRIGHT).value) {
          this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.BLOCKRIGHT)
        } else {
          this.currentState = this.currentState
        }
        break
      default:
        this.currentState = this.stateMachines.get(PARAM_NAME_ENUM.IDLE)
    }
  }
}

